package com.topway.dsmflex.thread.job;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import com.Consts;
import com.topway.dsmflex.Log;
import com.topway.dsmflex.model.synchro.DataSourceBean;
import com.topway.dsmflex.model.synchro.DataTableBean;
import com.topway.dsmflex.thread.services.SynchroServices;
import com.topway.dsmflex.util.ObjectSerializable;



/**
 * 同步执行（未使用）
 * 
 * @author liusy 2013-04-13
 *
 */
public class SynchroMonitor extends Thread {
	
	private static Logger log = Logger.getLogger(SynchroMonitor.class);

	private boolean flag = false;
	
	private boolean readConfig = true;
	
	private int SynchroResult = 0;
	
	private DataSourceBean source = null;
	
	private DataSourceBean target = null;
	
	private int nterval = 5;//5分钟
	
	private SynchroServices synchroServices = null;

	private List<DataTableBean> tableList = new ArrayList<DataTableBean>();
	
	private DataTableBean dt =null;
	
	private static SynchroMonitor synchroMonitor = null;
	
	public SynchroMonitor()
	{
		synchroServices = SynchroServices.getSynchroServices();
	}
	
	
	public synchronized static SynchroMonitor getSynchroMonitor()
	{
		if(null==synchroMonitor)
		{
			synchroMonitor = new SynchroMonitor();
			
		}
		return synchroMonitor;
	}
	
	
	
	@Deprecated
	@Override
	public synchronized void start() {
		super.start();
	}
	
	
	
	public synchronized void start(int nterval) {
		this.nterval = nterval;
		this.flag = true;
		this.readConfig = true;
		super.start();
	}


	@Override
	public void run() {
		while(true)
		{
			if(flag)
			{
				if(readConfig)
				{	
					Map<String, DataTableBean> mapTable = (Map<String, DataTableBean>) ObjectSerializable.readObject(Consts.DATAFILE_TABLE);
					
					if(null!=mapTable)
					{
						for(Entry<String,DataTableBean> entry:mapTable.entrySet())
						{
							tableList.add(entry.getValue());
						}
					}
					Map<String, DataTableBean> _mapTable = (Map<String, DataTableBean>) ObjectSerializable.readObject(Consts.DATAFILE_SQL);
					if(null!=_mapTable)
					{
						for(Entry<String,DataTableBean> entry:_mapTable.entrySet())
						{
							
							tableList.add(entry.getValue());
						}
						
					}
					
					this.readConfig = false;
				}

				Log.info("正在执行任务...");
				    for (int i = 0; i < tableList.size(); i++) {
						try {
							dt = tableList.get(i);
							if(dt.isRun())
							{
								SynchroResult=0;
								
								Log.info("正在同步表["+dt.getTableNameSource()+"]");
							
								SynchroResult = ntervalRun(dt);
								
								Log.info("源表["+dt.getTableNameSource()+"] 对目标表   ["+dt.getTableNameTarget()+"]  同步  ["+dt.getOperatorTarget()+"]完成，已同步["+SynchroResult+"]条数据!");
							}
		
						} catch (Exception e) {
							log.error(e.getMessage());
						}
					}
			
				    Log.info("任务完成,休息["+nterval+"]分钟后继续执行!");
				try {
					this.sleep(1000 * 60 * nterval);
				} catch (InterruptedException e) {
					log.error(e.getMessage());
				}
			}else
			{
				try {
					this.sleep(1000 * 60);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	
	private int ntervalRun(DataTableBean dt)
	{
		int result = 0;
		try {
			if(dt.getOperatorTarget().equals("UPDATE"))
				result = synchroServices.synchroUpdateData(dt);
			else if(dt.getOperatorTarget().equals("INSERT"))
				result = synchroServices.synchroInsertData(dt);
			else if(dt.getOperatorTarget().equals("INSERTUPDATE"))
				result = synchroServices.synchroInsertOrUpdateData(dt);
		} catch (SQLException e) {
			Log.error("同步表["+dt.getOperatorSource()+"]发生错误，忽略!"+e.getMessage());
		}	
		return result;
	}

	
	
	public void suspendSynchro()
	{
		this.flag = false;
	}
	
	public void  resumeSynchro()
	{
		this.flag = true;
		this.readConfig = true;
	}
	
	public boolean isReadConfig() {
		return readConfig;
	}


	public void setReadConfig(boolean readConfig) {
		this.readConfig = readConfig;
	}


	public int getNterval() {
		return nterval;
	}

	public void setNterval(int nterval) {
		this.nterval = nterval;
	}

	public boolean runState()
	{
		return this.flag;
	}
	
}
